<?php

/**
 * Request
 *
 * @author OC
 * @package System
 */
class Request
{

    /**
     * $_GET paraméterek
     *
     * @var Array
     */
    public $get = array();

    /**
     * $_POST paraméterek
     *
     * @var Array
     */
    public $post = array();

    /**
     * $_COOKIE paraméterek
     *
     * @var Array
 
    public $files = array();

    /**
     * $_SERVER paraméterek
     *
     * @var Array
     */
    public $server = array();


    /**
     * Gyakori web crawlerek user agentjei
     *
     * @var array
     */
    private $robotUserAgents = array(
        'bingbot',
        'AhrefsBot',
        'Googlebot',
        'MJ12bot',
        'msnbot',
        'YandexBot',
        'YandexImages',
        'TurnitinBot',
        'BLEXBot',
        'spbot',
        'Pingdom',
        'SISTRIX',
        'AdsBot-Google',
        'Exabot',
        'UptimeRobot',
        'LoadTimeBot',
        'linkdexbot',
        'psbot-page',
        'trendictionbot',
        'woopingbot',
        '200PleaseBot',
        'pmoz.info',
        'archive.org_bot',
        'MojeekBot',
        'Mail.RU_Bot',
        'socialbm_bot',
        'ClickTale',
        'niki-bot',
        'urlcheck-robot',
        'PagesInventory',
        'FreeWebMonitoring',
        'yacybot',
        'Wotbox',
        'Twitterbot',
        'CrawlDaddy',
        'psbot',
        'bitlybot',
        'woobot',
        'rogerbot',
        'AdMedia bot',
        'Slurp',
        'Grando-feed'
    );

    /**
     * @desc Azokat az urleket tartalmazza, amelyeket minden esetben megjelenítünk
     *
     * @var array
     */
    private $alwaysAllowedRoutes = array(
        'payment/pp_standard/callback',
        'information/contact/captcha',
        'common/contact',
        'feed/google_sitemap',
        'module/newsletter_subscribe/log'
    );

    /**
     * @var Registry
     */
    protected $registry = null;

    /**
     * Konstruktor
     */
    public function __construct($data = array())
    {
        $this->setData($data);

        if (!$this->getServer('HTTP_USER_AGENT', false)) {
            $this->server['HTTP_USER_AGENT'] = 'UNKNOWN_BROWSER';
        }
    }

    /**
     * @param array $data
     */
    public function setData($data = array())
    {
        $this->get = isset($data['get'])
            ? $this->clean($data['get']) : array();
        $this->post = isset($data['post'])
            ? $this->clean($data['post']) : array();
        $this->cookie = isset($data['cookie'])
            ? $this->clean($data['cookie']) : array();
        $this->files = isset($data['files'])
            ? $this->clean($data['files']) : array();
        $this->server = isset($data['server'])
            ? $this->clean($data['server']) : array();
    }

    /**
     * Registry beállítása
     *
     * @param $registry Registry
     */
    public function setRegistry(Registry $registry)
    {
        $this->registry = $registry;
    }

    /**
     * @return Array
     */
    public function getData()
    {
        return array(
            'get' => $this->get,
            'post' => $this->post,
            'cookie' => $this->cookie,
            'files' => $this->files,
            'server' => $this->server
        );
    }

    /**
     * Adatok tisztítása
     *
     * @param Array|String $data
     * @return Array|String
     */
    public function clean($data)
    {
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                unset($data[$key]);
                $data[$this->clean($key)] = $this->clean($value);
            }
        } else {
            $data = htmlspecialchars(
                mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data)),
                ENT_COMPAT,
                'UTF-8'
            );
        }
        return $data;
    }

    /**
     * Check if param is setted in $m array
     *
     * @param String $m (get|post|cookie|file|server)
     * @param String $name Name of param
     * @return Bool
     */
    protected function _hasParam($m, $name)
    {
        return isset($this->{$m}[$name]);
    }

    /**
     * Get param from $m array
     *
     * @param String $m (get|post|cookie|file|server)
     * @param String $name name of asked param
     * @param mixed $default value if param is not set in $m array
     * @return mixed
     */
    protected function _getParam($m, $name, $default = null)
    {
        if (null == $name) {
            return $this->{$m};
        }
        if (!$this->_hasParam($m, $name)) {
            return $default;
        }
        return $this->{$m}[$name];
    }

    /**
     * Get named param. Try order GET|POST|COOKIE|FILES|SERVER
     *
     * @param String $name Param name
     * @param mixed $default Return value if there is no any param with given name
     * @return mixed
     */
    public function getParam($name, $default = null)
    {
        foreach (array('get', 'post', 'cookie', 'files', 'server') as $m) {
            if ($this->_hasParam($m, $name)) {
                return $this->_getParam($m, $name, $default);
            }
        }
        return $default;
    }


    /**
     * Check if there is a GET|POST|COOKIE|FILES|SERVER param with given name
     *
     * @param String $name
     * @return Bool
     */
    public function hasParam($name = null)
    {
        foreach (array('get', 'post', 'cookie', 'files', 'server') as $m) {
            if ($this->_hasParam($m, $name)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get all GET|POST|COOKIE|FILES|SERVER merged into an array
     *
     * @return Array
     */
    public function getParams()
    {
        return array_merge_recursive(
            $this->get,
            $this->post,
            $this->cookie,
            $this->files,
            $this->server
        );
    }


    /**
     * Get Query ($_GET) param
     *
     * @param String $name Name of Query param
     * @param mixed $default Return value if $_GET[$name] not exists
     * @return mixed
     */
    public function getQuery($name = null, $default = null)
    {
        return $this->_getParam('get', $name, $default);
    }

    /**
     * Check if there is a Query ($_GET) param with given name
     *
     * @param String $name
     * @return Bool
     */
    public function hasQuery($name = null)
    {
        return $this->_hasParam('get', $name);
    }

    /**
     * Get POST param
     *
     * @param String $name name of POST param
     * @param mixed $default Return value if $_POST[$name] not exists
     * @return mixed
     */
    public function getPost($name = null, $default = null)
    {
        return $this->_getParam('post', $name, $default);
    }

    /**
     * Check if there is a POST param with given name
     *
     * @param String $name
     * @return Bool
     */
    public function hasPost($name = null)
    {
        return $this->_hasParam('post', $name);
    }

    /**
     * Get COOKIE param
     *
     * @param String $name name of COOKIE param
     * @param mixed $default Return value if $_COOKIE[$name] not exists
     * @return mixed
     */
    public function getCookie($name = null, $default = null)
    {
        return $this->_getParam('cookie', $name, $default);
    }

    /**
     * Check if there is a COOKIE param with given name
     *
     * @param String $name
     * @return Bool
     */
    public function hasCookie($name = null)
    {
        return $this->_hasParam('cookie', $name);
    }

    /**
     * Get FILE param
     *
     * @param String $name name of FILE param
     * @param mixed $default Return value if $_FILES[$name] not exists
     * @return mixed
     */
    public function getFile($name = null, $default = null)
    {
        return $this->_getParam('files', $name, $default);
    }

    /**
     * Check if there is a FILE param with given name
     *
     * @param String $name
     * @return Bool
     */
    public function hasFile($name = null)
    {
        return $this->_hasParam('files', $name);
    }

    /**
     * Get SERVER param
     *
     * @param String $name name of SERVER param
     * @param mixed $default Return value if $_SERVER[$name] not exists
     * @return mixed
     */
    public function getServer($name = null, $default = null)
    {
        return $this->_getParam('server', $name, $default);
    }

    /**
     * Check if there is a SERVER param with given name
     *
     * @param String $name
     * @return Bool
     */
    public function hasServer($name = null)
    {
        return $this->_hasParam('server', $name);
    }

    /**
     * Visszaadj az aktuális user-agentet
     *
     * @return String
     */
    public function getUserAgent()
    {
        return $this->server['HTTP_USER_AGENT'];
    }

    /**
     * Meghatározza user agent alapján, hogy robotok vagyunk-e
     *
     * @return bool
     */
    public function isRobot()
    {
        foreach ($this->robotUserAgents as $agentShortName) {
            if (stripos($this->getUserAgent(), $agentShortName) !== false) {
                return true;
            }
        }
        return false;
    }

    /**
     * Visszaadja, h az adott route paramétert mindig át kell e engednünk
     *
     * @return bool
     */
    public function isRouteAlwaysAllowed()
    {
        return in_array($this->getQuery('route'), $this->alwaysAllowedRoutes);
    }
}

//end
